﻿//***********************************************************************
// Assembly         : phpmk
// Author           : 
// Created          : 04-12-2010
//
// Last Modified By : 
// Last Modified On : 04-12-2010
// Description      : 
//
// Copyright        : (c) Another-D-Mention Software. All rights reserved.
//***********************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Phpmk.ADM.Parameters;
using phpmk.ADM.Commands.Update;
using phpmk.ADM.Out;
using phpmk.ADM.Commands;
using phpmk.ADM.Commands.Help;
using System.Windows.Forms;
using phpmk.ADM.Commands.Create;
using phpmk.ADM.Commands.Build;
using phpmk.ADM.Commands.Deploy;
using phpmk.ADM.Commands.Validate;
using phpmk.ADM.Commands.Log;
using phpmk.ADM.Core.Configuration;
using System.Resources;
using System.Reflection;
using phpmk.ADM.Utils;
using phpmk.ADM.Commands.Test;
using System.Collections.Specialized;

namespace phpmk.ADM.Core {
    class CoreApp {

        private ParameterParser parameters;
        private Dictionary<String, ICommand> commands;

        public ConfigFile Config;

        public CoreApp(ParameterParser parameters) {
            
            this.parameters = parameters;
            this.commands = new Dictionary<string, ICommand>();

            commands.Add("create", new CreateCommand());
            commands.Add("build", new BuildCommand());
            commands.Add("deploy", new DeployCommand());
            commands.Add("test", new TestCommand());
            commands.Add("log", new LogCommand());
            commands.Add("validate", new VaildateCommand());
            commands.Add("help", new HelpCommand());
            commands.Add("update", new UpdateCommand());

            this.Config = new ConfigFile();
        }

        public void Execute() {
            Output output = Output.GetInstance();
            // Show usage info
            if (parameters.Commands["main"].ContainsKey("?") || (!Config.Loaded && parameters.Commands.Count == 1)) {
                if (parameters.Commands["main"]["?"] != "true" && parameters.Commands["main"].ContainsKey("?")) {
                    if (commands.ContainsKey(parameters.Commands["main"]["?"])) {
                        commands[parameters.Commands["main"]["?"]].Help();
                        return;
                    } else {
                        output.Warning("No such command: " + parameters.Commands["main"]["?"]);
                        (commands["help"] as HelpCommand).PrintUsageInfo(commands);
                        return;
                    }   
                } else {
                    (commands["help"] as HelpCommand).PrintUsageInfo(commands);
                    if (!Config.Loaded) {
                        output.Write("");
                        output.Info(ErrorMessages.NoConfigFile);
                    }
                    return;
                }
            }

            if (parameters.Commands.ContainsKey("update")) {
                commands["update"].Execute(parameters.Commands["update"]);
                return;
            }

            if (parameters.Commands.ContainsKey("help") || parameters.Commands.ContainsKey("h")) {
                if (parameters.Commands["help"].ContainsKey("target")) {
                    if (commands.ContainsKey(parameters.Commands["help"]["target"])) {
                        commands[parameters.Commands["help"]["target"]].Help();
                    } else {
                        output.Warning("No such command: " + parameters.Commands["help"]["target"]);
                        (commands["help"] as HelpCommand).PrintUsageInfo(commands);
                        return;
                    }
                } else {
                    // show help of help
                    commands["help"].Help();
                    return;
                }
            }

            if (parameters.Commands.ContainsKey("create")) {
                commands["create"].Execute(parameters.Commands["create"]);
                return;
            }

            if (parameters.Commands.ContainsKey("validate")) {
                commands["validate"].Execute(parameters.Commands["validate"]);
                return;
            } 
            
            output.TimeStamp = true;

            // Execute command or chain of commands in this specific order
            if (parameters.Commands.ContainsKey("log")) {
                commands["log"].Execute(parameters.Commands["log"]);
            }

            // Execute command or chain of commands in this specific order
            if (parameters.Commands.ContainsKey("test")) {
                commands["test"].Execute(parameters.Commands["test"]);
            }

            output.Separator();
            output.Write("Project: " + Config.Model.Profile.Name);
            output.Write("Version: " + Config.Model.Profile.Version);
            output.Separator();

            try {
                if (parameters.Commands.ContainsKey("build")) {
                    commands["build"].Execute(parameters.Commands["build"]);
                } else {
                    commands["build"].Execute(new StringDictionary());
                }

                try {
                    if (parameters.Commands.ContainsKey("deploy")) {
                        commands["deploy"].Execute(parameters.Commands["deploy"]);
                    } else {
                        commands["deploy"].Execute(new StringDictionary());
                    }
                } catch (DeployException ex) {
                    output.Error(ex.Message);
                }

            } catch (BuildException ex) {
                output.Error(ex.Message);
            }
        }
    }
}
